package com.hsh.tools;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.hsh.tools.handler.BusinessException;
import com.hsh.vo.dto.ActiveUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.Date;

public class JWTUtils {

    private static final Logger logger = LoggerFactory.getLogger(JWTUtils.class);

    /**
     * 过期时间3天
     */
    private static final long EXPIRE_TIME = 3 * 24 * 60 * 60 * 1000;

//    /**
//     * 过期时间6小时
//     */
//    private static final long EXPIRE_TIME = 6 * 60 * 60 * 1000;

//    /**
//     * 过期时间1 分钟
//     */
//    private static final long EXPIRE_TIME = 60 * 1000;


    //

    /**
     * 生成签名
     */
    public static String signSimple(String username, String secret) {
        try {
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            return JWT.create()
                    .withClaim("username", username)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    /**
     * 生成签名,6小时后过期
     *
     * @param activeUser 存储信息
     * @param secret     db pwd
     */
    public static String signLogin(ActiveUser activeUser, String secret) {
        try {
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            return JWT.create()
                    .withClaim(FinalData.ACTIVE_USER, JSON.toJSONString(activeUser))
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new BusinessException("生成token 失败！");
        }
    }

    /**
     * 校验token
     */
    public static boolean verifyToken(String token, ActiveUser activeUser, String secret) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim(FinalData.ACTIVE_USER, JSON.toJSONString(activeUser))
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获取当前活动用户
     */
    public static ActiveUser getActiveUser(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return JSON.parseObject(jwt.getClaim(FinalData.ACTIVE_USER).asString(), ActiveUser.class);
        } catch (JWTDecodeException e) {
            logger.error(e.getMessage());
            throw new BusinessException("token 解析失败！");
        }
    }

    /**
     * 判断是否过期
     */
    public static boolean isExpire(String token) {
        DecodedJWT jwt = JWT.decode(token);
        long l = jwt.getExpiresAt().getTime() - System.currentTimeMillis();
        System.out.println("剩余: " + l + "ms");
        System.out.println(l / 1000 / 60 + "分钟");
        System.out.println(l / 1000 / 60 / 60 + "小时");
        System.out.println(l / 1000 / 60 / 60 / 24 + "~~ 天");
        return System.currentTimeMillis() > jwt.getExpiresAt().getTime();
    }


    public static void main(String[] args) {
        // 生成token
        // 前台  原密码  盐：原密码长度    密码加密规则   原密码md5 加密三次 然后原密码长度作为盐 md5加密一次
        // 密码 123666
        // 前台传入值
        String oldPwd = "123666";
        String newPwd = Md5Utils.md5Hex3(oldPwd, oldPwd.length() + "");
        System.out.println("前台传入值：" + newPwd);

        // 后端加密规则，通过前台传入 加密1024次
        String dbSlat = "hsh";
        System.out.println("db: " + Md5Utils.md5Encryption(newPwd, dbSlat));

//
//        //
//        System.out.println("~~~~~~~~~~~~~~~~~6 天~~~~~~~~~~~~~~~~~~~~");
//        String jwtToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY3RpdmVVc2VyIjoie1wiZGVwdEZsYWdcIjp0cnVlLFwiaG9zdFwiOlwiMTI3LjAuMC4xXCIsXCJsb2NhdGlvblwiOlwi5YaF572RSVB8MHwwfOWGhee9kUlQfOWGhee9kUlQXCIsXCJsb2dpblR5cGVcIjpcInVzZXJuYW1lUGFzc3dvcmRcIixcIm1lbnVzXCI6W3tcImRpc2FibGVkXCI6MCxcImljb25cIjpcImVsLWljb24tcy1mbGFnXCIsXCJtZW51SWRcIjoxLFwibWVudU5hbWVcIjpcIuivt-WBh1wiLFwib3BlblwiOjAsXCJwYXJlbnRJZFwiOjAsXCJwZXJtc1wiOlwiXCIsXCJzZXFcIjoxLFwidHlwZVwiOjAsXCJ1cmxcIjpcIlwifSx7XCJkaXNhYmxlZFwiOjAsXCJpY29uXCI6XCJlbC1pY29uLXMtZmxhZ1wiLFwibWVudUlkXCI6MixcIm1lbnVOYW1lXCI6XCLor7flgYfnlLPor7dcIixcIm9wZW5cIjowLFwicGFyZW50SWRcIjoxLFwicGVybXNcIjpcInJlY29yZC1hcHBseS1mb3I6dmlld1wiLFwic2VxXCI6MixcInR5cGVcIjowLFwidXJsXCI6XCIvcmVjb3JkLWFwcGx5LWZvclwifSx7XCJkaXNhYmxlZFwiOjAsXCJpY29uXCI6XCJlbC1pY29uLXMtZmxhZ1wiLFwibWVudUlkXCI6MyxcIm1lbnVOYW1lXCI6XCLor7flgYforrDlvZVcIixcIm9wZW5cIjowLFwicGFyZW50SWRcIjoxLFwicGVybXNcIjpcImxlYXZlLXJlY29yZDp2aWV3XCIsXCJzZXFcIjozLFwidHlwZVwiOjAsXCJ1cmxcIjpcIi9sZWF2ZS1yZWNvcmRcIn0se1wiZGlzYWJsZWRcIjowLFwiaWNvblwiOlwiZWwtaWNvbi1zLWZsYWdcIixcIm1lbnVJZFwiOjQsXCJtZW51TmFtZVwiOlwi6K-35YGH5aSE55CGXCIsXCJvcGVuXCI6MCxcInBhcmVudElkXCI6MSxcInBlcm1zXCI6XCJsZWF2ZS1kaXNwb3NlOnZpZXdcIixcInNlcVwiOjQsXCJ0eXBlXCI6MCxcInVybFwiOlwiL2xlYXZlLWRpc3Bvc2VcIn0se1wiZGlzYWJsZWRcIjowLFwiaWNvblwiOlwiZWwtaWNvbi1zLWZsYWdcIixcIm1lbnVJZFwiOjUsXCJtZW51TmFtZVwiOlwi6K-35YGH55Sz6K-35o-Q5LqkXCIsXCJvcGVuXCI6MCxcInBhcmVudElkXCI6MixcInBlcm1zXCI6XCJyZWNvcmQtYXBwbHktZm9yOmFkZFwiLFwic2VxXCI6NSxcInR5cGVcIjoxfV0sXCJuaWNrbmFtZVwiOlwi6buE5oCd5rW3XCIsXCJwYXNzd29yZFwiOlwiMjdkZTU1NjFmNzRlZmM0YzgzMGVkNDRjMjZjOTI2OWRcIixcInBlcm1pc3Npb25zXCI6W1wicmVjb3JkLWFwcGx5LWZvcjphZGRcIl0sXCJyb2xlc1wiOlt7XCJyZW1ha2VzXCI6XCLlkZjlt6VcIixcInJvbGVJZFwiOjIsXCJyb2xlTmFtZVwiOlwi5ZGY5belXCIsXCJzZXFcIjoxfV0sXCJzYWx0XCI6XCJoc2hcIixcInN5c3RlbUhvc3RcIjpcIjEyNy4wLjAuMVwiLFwidXJsc1wiOltcIi9yZWNvcmQtYXBwbHktZm9yXCIsXCIvbGVhdmUtcmVjb3JkXCIsXCIvbGVhdmUtZGlzcG9zZVwiXSxcInVzZXJcIjp7XCJhY2NvdW50U3RhdHVzXCI6MSxcImFjdGl2YXRpb25TdGF0dXNcIjoxLFwiZGVsRmxhZ1wiOjAsXCJlbWFpbFwiOlwiMTY3OTA5MWM1YTg4MGZhZjZmYjVlNjA4N2ViMWIyZGNcIixcImdlbmRlclwiOjEsXCJpbW1lZGlhdGVMZWFkZXJcIjpcInl4YlwiLFwibW9iaWxlXCI6XCIxMTExMTExMTExMVwiLFwibmlja25hbWVcIjpcIum7hOaAnea1t1wiLFwicGFzc3dvcmRcIjpcIjI3ZGU1NTYxZjc0ZWZjNGM4MzBlZDQ0YzI2YzkyNjlkXCIsXCJzYWx0XCI6XCJoc2hcIixcInVzZXJJZFwiOlwiaHNoXCIsXCJ1c2VybmFtZVwiOlwi6buE5oCd5rW3XCJ9LFwidXNlcklkXCI6XCJoc2hcIixcInVzZXJuYW1lXCI6XCLpu4TmgJ3mtbdcIn0iLCJleHAiOjE2MjUxMDA5MzN9.QTO2SiUawTro7yewKewNmA6GNndnSMA6IftCrjstAZI";
//        ActiveUser activeUser = getActiveUser(jwtToken);
//        System.out.println(activeUser);
//        System.out.println(JSON.toJSONString(activeUser, true));
//        System.out.println(isExpire(jwtToken));
//        /*
//            18820215ms
//            313分钟
//            false
//         */
//
//        // 测试token 失效
////        前台传入值：1679091c5a880faf6fb5e6087eb1b2dc
////                usernamePassword
////        黄思海
////
////        27de5561f74efc4c830ed44c26c9269d
//        //
//        System.out.println("测试token失效时间~~~~~~~");
//        String pwdSalt = Md5Utils.md5Encryption("1679091c5a880faf6fb5e6087eb1b2dc", "hsh");
//        String tokenTodo = signSimple("黄思海", pwdSalt);
//        System.out.println(tokenTodo);
//        String todo = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MjQ3NjQxODYsInVzZXJuYW1lIjoi6buE5oCd5rW3In0.lz3lfFCyZ1XoSKLdeWYFw4_OLFenzfBCSAMtdiCfK1U";
//        System.out.println(isExpire(todo));

    }
}

